package activity

import (
	"context"
	"strconv"
	"strings"

	"mall/service/backend/api/internal/logic/promotion/util"
	"mall/service/backend/api/internal/svc"
	"mall/service/backend/api/internal/types"
	"mall/service/backend/api/internal/utils/parse"

	// enum "mall/service/backend/common/enum/promotion"
	"mall/service/backend/common/i18n"
	"mall/service/backend/common/utils/pointy"
	"mall/service/product/rpc/productclient"
	"mall/service/promotion/rpc/promotionclient"

	"github.com/zeromicro/go-zero/core/logx"
)

type GetActivityProductListLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewGetActivityProductListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetActivityProductListLogic {
	return &GetActivityProductListLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *GetActivityProductListLogic) GetActivityProductList(
	req *types.ActivityProductListReq,
) (resp *types.ActivityProductListResp, err error) {
	page, pageSize := parse.ParsePageInfo(
		req.Current,
		req.PageSize,
		l.svcCtx.Config.Query.DefaultAmount,
		l.svcCtx.Config.Query.MaxAmount,
	)

	var status uint32
	if req.Status != nil {
		status = *req.Status + 1
	}

	orderBys := util.ParseSorter(req.Sorter)
	filterBys := util.ParseFilter(req.Filter)

	data, err := l.svcCtx.PromotionRpc.BackendGetActivityRelationshipById(l.ctx, &promotionclient.ActivityRelationListReq{
		Page:         page,
		PageSize:     pageSize,
		ActivityId:   *req.ActivityId,
		WithProducts: pointy.GetPointer(uint32(1)),
		ProductType:  req.ProductType,
		Status:       &status,
		OrderBy:      orderBys,
		FilterBy:     filterBys,
	})
	if err != nil {
		return nil, err
	}

	resp = &types.ActivityProductListResp{
		BaseDataInfo: types.BaseDataInfo{
			Success: true,
			Msg:     l.svcCtx.Trans.Trans(l.ctx, i18n.Success),
		},
		Data: types.ActivityProductListInfo{
			BaseListInfo: types.BaseListInfo{
				Current:  page,
				PageSize: pageSize,
				Total:    data.GetTotal(),
			},
		},
	}

	var skuIds []string
	activityProductMap := make(map[uint64]*promotionclient.ActivityProductInfo)
	for _, v := range data.Products {
		if v.SkuId != nil && *v.SkuId > 0 {
			skuIds = append(skuIds, strconv.FormatInt(int64(*v.SkuId), 10))
			activityProductMap[*v.SkuId] = v
		}
	}
	if len(skuIds) > 0 {
		res, err := l.svcCtx.ProductRpc.BackendGetProductList(l.ctx, &productclient.ProductListReq{
			SkuIds: pointy.GetPointer(strings.Join(skuIds, ",")),
		})
		if err != nil {
			return nil, err
		}

		if len(res.List) > 0 {
			for _, v := range res.List {
				var media []*types.MediaInfo
				var skus []*types.ActivityProductSkuInfo
				if len(v.Media) > 0 {
					for _, vv := range v.Media {
						if vv.Id != nil && vv.Url != nil {
							media = append(media, &types.MediaInfo{
								Id:  vv.Id,
								Url: vv.Url,
							})
						}
					}
				}
				if len(v.Skus) > 0 {
					for _, vv := range v.Skus {
						var productType *uint32
						var price *string
						var inventory *uint64
						var checked bool
						if vv.Id != nil && *vv.Id > 0 {
							if info, ok := activityProductMap[*vv.Id]; ok {
								productType = info.ProductType
								price = info.Price
								inventory = info.Inventory
								checked = true
							}
						}
						var optKeys []string
						if len(vv.Specs) > 0 {
							for _, spec := range vv.Specs {
								if len(spec.Options) > 0 {
									for _, opt := range spec.Options {
										if opt.Label != nil && len(*opt.Label) > 0 {
											optKeys = append(optKeys, *opt.Label)
										}
									}
								}
							}
						}
						skus = append(skus, &types.ActivityProductSkuInfo{
							ProductType: productType,
							ProductId:   v.Id,
							SkuId:       vv.Id,
							SkuKey:      pointy.GetPointer(strings.Join(optKeys, " ")),
							Price:       price,
							Inventory:   inventory,
							Checked:     checked,
						})
					}
				}
				resp.Data.List = append(resp.Data.List, &types.ActivityProductInfo{
					ProductId: v.Id,
					Title:     v.Title,
					Slug:      v.Slug,
					Media:     media,
					Skus:      skus,
				})
			}
		}
	}

	return resp, nil
}
